package com.cosmoplat.xikai.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cosmoplat.xikai.business.domain.BaseDeliveryInfo;
import com.cosmoplat.xikai.business.domain.BaseDispatchTask;
import com.cosmoplat.xikai.business.domain.dto.materialRequirement.MaterialRequirementQueryDTO;
import com.cosmoplat.xikai.business.domain.mes.req.MesQrCodeRequest;
import com.cosmoplat.xikai.business.domain.mes.result.MesQrCodeResult;
import com.cosmoplat.xikai.business.domain.vo.MaterialRequirementVo;
import com.cosmoplat.xikai.business.enums.MaterialEnum;
import com.cosmoplat.xikai.business.service.BaseAlarmRecordService;
import com.cosmoplat.xikai.business.service.BaseDeliveryInfoService;
import com.cosmoplat.xikai.business.mapper.BaseDeliveryInfoMapper;
import com.cosmoplat.xikai.business.service.BaseDispatchTaskService;
import com.cosmoplat.xikai.business.service.MesRequestService;
import com.cosmoplat.xikai.common.enums.DelFlagEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author 22047582
 * @description 针对表【base_delivery_info】的数据库操作Service实现
 * @createDate 2025-01-07 13:51:30
 */
@Slf4j
@Service
public class BaseDeliveryInfoServiceImpl extends ServiceImpl<BaseDeliveryInfoMapper, BaseDeliveryInfo>
        implements BaseDeliveryInfoService {

    @Autowired
    private MesRequestService mesRequestService;

    @Autowired
    private BaseDispatchTaskService baseDispatchTaskService;

    @Autowired
    private BaseAlarmRecordService alarmRecordService;

    @Override
    public List<MaterialRequirementVo> queryMaterialRequirement(MaterialRequirementQueryDTO queryDTO) {
        return this.getBaseMapper().queryMaterialRequirement(queryDTO);
    }

    @Override
    public List<BaseDeliveryInfo> getListByTaskId(String taskId) {
        QueryWrapper<BaseDeliveryInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(BaseDeliveryInfo::getTaskId, taskId)
                .eq(BaseDeliveryInfo::getIsDelete, DelFlagEnum.NORMAL.getCode());
        return list(queryWrapper);
    }

    @Override
    public BaseDeliveryInfo getByTaskIdAndMaterialCode(String taskId, String materialCode) {
        QueryWrapper<BaseDeliveryInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(BaseDeliveryInfo::getTaskId, taskId)
                .eq(BaseDeliveryInfo::getMaterialCode, materialCode)
                .eq(BaseDeliveryInfo::getIsDelete, DelFlagEnum.NORMAL.getCode());
        return getOne(queryWrapper);
    }

    @Override
    public void updateStockQtyForScanCode(String qrCode) {
        BaseDispatchTask doingTask = baseDispatchTaskService.getDoingTask();
        if (doingTask == null) {
            log.info("没有进行中的任务，查找最后完成的任务");
            doingTask = baseDispatchTaskService.getLastTask();
        }

        MesQrCodeRequest mesQrCodeRequest = new MesQrCodeRequest();
        if (doingTask == null) {
            log.error("没有进行中的任务，没有最后完成的任务");
            return;
        }
        mesQrCodeRequest.setId(doingTask.getTaskId());
        mesQrCodeRequest.setContainerNo(qrCode);
        MesQrCodeResult mesQrCodeResult = mesRequestService.scanCodeToMaterialQty(mesQrCodeRequest);
        log.info("扫描条码获取物料信息成功，条码：{}, mes返回结果:{}", qrCode, mesQrCodeResult);
        if (mesQrCodeResult == null) {
            log.error("扫描条码获取物料信息失败，条码：{}", qrCode);
            return;
        }
        Boolean checkMaterialCodeResult = checkMaterialCode(mesQrCodeResult, doingTask.getTaskId());
        // mes返回的物料编码不存在, 通知mes进行告警
        if (!checkMaterialCodeResult) {
            alarmRecordService.materialErrorCallMes(doingTask, mesQrCodeResult.getSku(), "当前执行的任务中，物料编码不存在" + mesQrCodeResult.getSku());
        }
        // 检查物料数量
        if (mesQrCodeResult.getQty() == null || mesQrCodeResult.getQty() <= 0) {
            log.error("检查物料数量错误，条码：{}", mesQrCodeResult);
            alarmRecordService.materialErrorCallMes(doingTask, mesQrCodeResult.getSku(), "当前执行的任务中，物料编码对应的配送数量错误" + mesQrCodeResult.getSku());
            return;
        }
        // 更新库存数量
        BaseDeliveryInfo deliveryInfo = getByTaskIdAndMaterialCode(doingTask.getTaskId(), mesQrCodeResult.getSku());
        // 加库存
        if (deliveryInfo.getStockQty() == null) {
            log.error("物料的库存数量未更新，数量为空，默认为0: {}", deliveryInfo.getMaterialCode());
            deliveryInfo.setStockQty(BigDecimal.ZERO);
        }
        deliveryInfo.setStockQty(deliveryInfo.getStockQty().add(new BigDecimal(mesQrCodeResult.getQty())));
        updateById(deliveryInfo);
    }

    @Override
    public void deductionStockQty(BaseDispatchTask doingTask) {
        List<BaseDeliveryInfo> deliveryInfoList = getListByTaskId(doingTask.getTaskId());
        for (BaseDeliveryInfo deliveryInfo : deliveryInfoList) {

            // 需要扣减库存的物料
            if (MaterialEnum.inStockMaterial(deliveryInfo.getMaterialCode())) {
                if (deliveryInfo.getStockQty() == null) {
                    log.error("物料的库存数量未更新，无法扣减库存, 设置库存为0：{}", deliveryInfo.getMaterialCode());
                    deliveryInfo.setStockQty(BigDecimal.ZERO);
                }
                if (deliveryInfo.getStockQty().compareTo(deliveryInfo.getRequiredQty()) < 0) {
                    log.warn("物料：{} 库存不足，当前库存：{}，所需数量：{}", deliveryInfo.getMaterialCode(), deliveryInfo.getStockQty(), deliveryInfo.getRequiredQty());
                }
                // 扣库存
                deliveryInfo.setStockQty(deliveryInfo.getStockQty().subtract(deliveryInfo.getRequiredQty()));
                updateById(deliveryInfo);
            }
        }
    }

    /**
     * 检查mes的物料编码是否存在
     *
     * @param result
     * @param taskId
     * @return
     */
    private Boolean checkMaterialCode(MesQrCodeResult result, String taskId) {
        BaseDeliveryInfo deliveryInfo = getByTaskIdAndMaterialCode(taskId, result.getSku());
        if (deliveryInfo == null) {
            log.error("mes返回的物料编码不存在，条码：{}, mes返回结果:{}", result.getSku(), result);
            return false;
        }
        return true;
    }
}




